﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace d1.订单管理
{
    internal class Program
    {

        static void Main(string[] args)
        {
            OrderService Order_All = new OrderService();

            OrderDetail detail_1 = new OrderDetail("商品1", 10, 2);
            OrderDetail detail_2 = new OrderDetail("商品2", 20, 3);
            OrderDetail detail_3 = new OrderDetail("商品3", 30, 4);
            OrderDetail detail_4 = new OrderDetail("商品4", 40, 5);
            OrderDetail detail_5 = new OrderDetail("商品5", 50, 6);

            Order order_1 = new Order()
            {
                Order_ID = "001",
                Customer = "小明",
                Order_Time = DateTime.Parse("2022-01-01"),
                Details = new List<OrderDetail>() { detail_1, detail_2 }
            };
            Order order_2 = new Order()
            {
                Order_ID = "002",
                Customer = "小红",
                Order_Time = DateTime.Parse("2022-02-02"),
                Details = new List<OrderDetail>() { detail_3, detail_4 }
            };
            Order order_3 = new Order()
            {
                Order_ID = "003",
                Customer = "小王",
                Order_Time = DateTime.Parse("2022-03-03"),
                Details = new List<OrderDetail>() { detail_1, detail_4 }
            };


            Order_All.Add_Order(order_1);
            Order_All.Add_Order(order_2);
            Order_All.Add_Order(order_3);
            Console.WriteLine("原有的订单列表：");
            Console.WriteLine(Order_All);
            
            Console.WriteLine("请输入实现功能的序号(1:添加订单，2:删除订单，3:修改订单，4:查询订单，5：打印订单，0：退出)：");
            int Option;
            Option = int.Parse(Console.ReadLine());
            while (Option != 0)
            {
                switch (Option)
                {
                    case 0:
                        break;
                    case 1:
                        Order order_add = Add_Fun();
                        Order_All.Add_Order(order_add);
                        break;
                    case 2:
                        Console.WriteLine("请输入订单号：");
                        string Order_ID = Console.ReadLine();
                        Order_All.Remove_Order(Order_ID);
                        break;
                    case 3:
                        Order order_update = Add_Fun();
                        Order_All.Update_Order(order_update);
                        break;
                    case 4:
                        Query_Fun(Order_All);
                        break;
                    case 5:
                        Order_All.Sort_Orders();
                        Console.WriteLine(Order_All);
                        break;
                    default:
                        Console.WriteLine("输入不符合要求！");
                        break;
                }
                Console.WriteLine("请输入实现功能的序号(1:添加订单，2:删除订单，3:修改订单，4:查询订单，5：打印订单，0：退出)：");
                Option = int.Parse(Console.ReadLine());
            }

            Order Add_Fun()     //控制台添加功能
            {
                Console.WriteLine("请输入订单号：");
                string Order_ID = Console.ReadLine();
                Console.WriteLine("请输入客户名称：");
                string Customer = Console.ReadLine();
                Console.WriteLine("请输入下单时间：");
                DateTime Order_Time = DateTime.Parse(Console.ReadLine());

                Order order = new Order()
                {
                    Order_ID = Order_ID,
                    Customer = Customer,
                    Order_Time = Order_Time,
                    Details = new List<OrderDetail>() { }
                };

                Console.WriteLine("请输入订单中的商品种类数量：");
                int N = int.Parse(Console.ReadLine());
                for (int i = 0; i < N; i++)
                {
                    Console.WriteLine($"请输入第{i + 1}个商品的信息：");
                    Console.WriteLine("商品名：");
                    string Item_Name = Console.ReadLine();
                    Console.WriteLine("商品单价：");
                    double Price = double.Parse(Console.ReadLine());
                    Console.WriteLine("商品数量：");
                    int Quantity = int.Parse(Console.ReadLine());
                    OrderDetail detail_i = new OrderDetail(Item_Name, Price, Quantity);
                    order.Details.Add(detail_i);
                }
                return order;
            }

            void Query_Fun(OrderService Order)
            {
                Console.WriteLine("请选择查询依据(1:订单号，2:商品名称，3:客户，4:订单金额，0：退出)：");
                int op = int.Parse(Console.ReadLine());
                switch (op)
                {
                    case 1:
                        Console.WriteLine("请输入订单号：");
                        string Order_ID = Console.ReadLine();
                        List<Order> output_1 = Order.QueryOrdersBy_OrderId(Order_ID);
                        if (output_1.Count == 0)
                        {
                            Console.WriteLine("不存在此订单号！\n");
                        }
                        else
                        {
                            OrderService Output = new OrderService(output_1);
                            Console.WriteLine(Output);
                        }
                        break;
                    case 2:
                        Console.WriteLine("请输入商品名称：");
                        string Item_Name = Console.ReadLine();
                        List<Order> output_2 = Order.QueryOrdersBy_ItemName(Item_Name);
                        if (output_2.Count == 0)
                        {
                            Console.WriteLine("不存在此商品！\n");
                        }
                        else
                        {
                            OrderService Output = new OrderService(output_2);
                            Console.WriteLine(Output);
                        }
                        break;
                    case 3:
                        Console.WriteLine("请输入客户名字：");
                        string Customer = Console.ReadLine();
                        List<Order> output_3 = Order.QueryOrdersBy_Customer(Customer);
                        if (output_3.Count == 0)
                        {
                            Console.WriteLine("不存在此客户！\n");
                        }
                        else
                        {
                            OrderService Output = new OrderService(output_3);
                            Console.WriteLine(Output);
                        }
                        break;
                    case 4:
                        Console.WriteLine("请输入订单金额：");
                        int Total_Amount = int.Parse(Console.ReadLine());
                        List<Order> output_4 = Order.QueryOrdersBy_TotalAmount(Total_Amount);
                        if (output_4.Count == 0)
                        {
                            Console.WriteLine("不存在此订单金额！\n");
                        }
                        else
                        {
                            OrderService Output = new OrderService(output_4);
                            Console.WriteLine(Output);
                        }
                        break;
                    default:
                        Console.WriteLine("输入不符合要求！");
                        break;
                }
            }

        }
    }
}


class OrderDetail   
{
    public string Item_Name { get; set; }   //商品名称
    public double Price { get; set; }       //商品单价
    public int Quantity { get; set; }       //商品数量

    public OrderDetail(string Item_Name, double Price, int Quantity)
    {
        this.Item_Name = Item_Name;
        this.Price = Price;
        this.Quantity = Quantity;
    }

    public override bool Equals(object obj)     //重写Equals方法
    {
        if (obj == null || !(obj is OrderDetail))   //若为空或者不是OrderDetail类，则直接返回false
        {
            return false;
        }
        else
        {
            OrderDetail other = (OrderDetail)obj;   //强制类型转换，将传入的object基类转化为OrderDetail类，不然无法比较
            bool if_Equal = (this.Item_Name == other.Item_Name) 
                            && (this.Price == other.Price) 
                            && (this.Quantity == other.Quantity);
            return if_Equal;
        }
    }

    public override int GetHashCode()   //重写哈希表方法，因为一般重写了Equals方法都要重写GetHashCode方法
    {
        return base.GetHashCode();
    }

    public override string ToString()   //重写ToString方法
    {
        return $"商品名称: {Item_Name}, 单价: {Price}, 数量: {Quantity}";
    }
}

class Order
{
    public string Order_ID { get; set; }    //订单号
    public string Customer { get; set; }    //客户
    public DateTime Order_Time { get; set; } //下单时间
    public List<OrderDetail> Details { get; set; }  //下单明细

    public double Total_Amount      //总金额
    {
        get
        {
            return Details.Sum(d => d.Price * d.Quantity);  //调用List的Sum方法并用lamda表达式进行累加
        }
    }

    public override bool Equals(object obj)
    {
        if (obj==null || !(obj is Order))
        {
            return false;
        }
        else
        {
            Order other = (Order)obj;
            bool if_Equal = (this.Order_ID == other.Order_ID)
                            && (this.Customer == other.Customer)
                            && (this.Order_Time == other.Order_Time);
            //SequenceEqual会比较两个序列中的元素是否一一对应相等
            if_Equal = if_Equal && this.Details.SequenceEqual(other.Details);
            return if_Equal;
        }
    }
    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public override string ToString()
    {
        return $"订单号: {Order_ID}, 客户: {Customer}, 时间: {Order_Time}, 总金额: {Total_Amount}";
    }

}

class OrderService
{
    public List<Order> Orders = new List<Order>();
    public OrderService()
    {
    }
    public OrderService(List<Order> Orders)
    {
        this.Orders = Orders;
    }
    public void Add_Order(Order Order_Add)      //添加订单功能
    {
        if (Orders.Contains(Order_Add))     //Contains方法调用Equals方法，用于判断一个元素是否存在于List中
        {
            throw new Exception($"订单{Order_Add.Order_ID }已存在，无法进行添加！");
        }
        else
        {
            Orders.Add(Order_Add);      //若不存在，则添加元素
        }
    }
    public void Remove_Order(string Order_ID)   //删除订单功能
    {
        //FirstOrDefault是Linq中的一个方法，返回序列中的第一个元素，若不存在则返回null
        Order Order_Re = Orders.FirstOrDefault(o => o.Order_ID == Order_ID);
        if (Order_Re == null)
        {
            throw new Exception($"订单 {Order_ID} 未找到，无法进行删除！");
        }
        Orders.Remove(Order_Re);
    }
    public void Update_Order(Order Order_New)    //修改订单功能
    {
        Order Order_Old = Orders.FirstOrDefault(o => o.Order_ID == Order_New.Order_ID);
        if (Order_Old == null)
        {
            throw new Exception($"订单 {Order_New.Order_ID} 未找到，无法进行更新!");
        }
        Orders.Remove(Order_Old);
        Orders.Add(Order_New);
    }

    //四个查询功能：
    public List<Order> QueryOrdersBy_OrderId(string Order_ID)   //按照订单号进行查询
    {
        //Linq返回的是IEnumerable<T>类型，故要用ToList()转化为List类
        return Orders.Where(o => o.Order_ID == Order_ID).OrderBy(o => o.Total_Amount).ToList();
    }
    public List<Order> QueryOrdersBy_ItemName(string Item_Name) //按照商品名称进行查询
    {
        return Orders.Where(o => o.Details.Any(d => d.Item_Name == Item_Name)).OrderBy(o => o.Total_Amount).ToList();
    }
    public List<Order> QueryOrdersBy_Customer(string customer)  //按照客户进行查询
    {
        return Orders.Where(o => o.Customer == customer).OrderBy(o => o.Total_Amount).ToList();
    }
    public List<Order> QueryOrdersBy_TotalAmount(double Amount) //按照订单金额进行查询
    {
        return Orders.Where(o => o.Total_Amount == Amount).OrderBy(o => o.Total_Amount).ToList();
    }

    public void Sort_Orders(string method = "Order_ID")  //查询功能：默认method为按照订单号排序
    {
        if (method == "Order_ID")
        {
            Orders.Sort((o1, o2) => o1.Order_ID.CompareTo(o2.Order_ID));
        }else if (method == "Total_Amount")
        {
            Orders.Sort((o1, o2) => o1.Total_Amount.CompareTo(o2.Total_Amount));
        }
        else
        {
            Console.WriteLine("没有提供此类查询方法！");
        }
        
    }
    public override string ToString()
    {
        string Output = "";
        foreach (var order in Orders)
        {
            Output += order.ToString() + "\n";
            foreach (var detail in order.Details)
            {
                Output += detail.ToString() + "\n";
            }
        }
        Output += "\n";
        return Output;
    }
}